import 'dart:math';
import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';

import 'hero_bar_widget.dart';
import 'hero_widget.dart';

/// 单个Image图片,点击查看大图实现
///
/// 注意: 同一个页面, imageUrl不允许相同,否则会报错
typedef HeroDoubleClickAnimationListener = void Function();

class SlideHeroImagePage extends StatefulWidget {
  const SlideHeroImagePage({
    required this.imageUrl,
    required this.heroTag,
    this.reLoadImage = false,
  });

  /// 图片URL全路径
  final String imageUrl;

  final String heroTag;

  /// 加载失败后,是否点击刷新
  final bool reLoadImage;
  @override
  _SlideHeroImagePageState createState() => _SlideHeroImagePageState();
}

class _SlideHeroImagePageState extends State<SlideHeroImagePage>
    with TickerProviderStateMixin {
  GlobalKey<ExtendedImageSlidePageState> slidePagekey =
      GlobalKey<ExtendedImageSlidePageState>();

  // 控制双击放大动画
  Animation<double>? _doubleClickAnimation;
  // 动画控制器
  AnimationController? _doubleClickAnimationController;
  HeroDoubleClickAnimationListener? _doubleClickAnimationListener;
  List<double> doubleTapScales = <double>[1.0, 2.0, 3.0];

  @override
  void initState() {
    // 初始化双击动画控制器
    _doubleClickAnimationController = AnimationController(
      duration: const Duration(milliseconds: 150),
      vsync: this,
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Theme(
      data: Theme.of(context).copyWith(
        dialogBackgroundColor: Color(0xFF333333),
      ),
      child: Stack(
        children: <Widget>[
          Positioned.fill(
            child: ExtendedImageSlidePage(
              key: slidePagekey,
              child: HeroWidget(
                child: ExtendedImage.network(
                  widget.imageUrl,
                  // enableSlideOutPage: true,
                  mode: ExtendedImageMode.gesture,
                  loadStateChanged: _loadStateChanged,
                  // 设置Hero划出动画
                  heroBuilderForSlidingPage: (Widget result) {
                    return result;
                  },
                  initGestureConfigHandler: _heroBuilderForSlidingPage,
                  onDoubleTap: _onDoubleTap,
                ),
                tag: "${widget.heroTag}",
                slideType: SlideType.onlyImage,
                slidePagekey: slidePagekey,
              ),
              slideAxis: SlideAxis.both,
              slideType: SlideType.onlyImage,
            ),
          ),
          HeroBarWidget(
            onTap: () {
              slidePagekey.currentState?.popPage();
              Navigator.pop(context);
            },
          ),
        ],
      ),
    );
  }

  // @override
  // Widget build(BuildContext context) {
  //   return Theme(
  //     data: Theme.of(context).copyWith(dialogBackgroundColor: Colors.black),
  //     child: ExtendedImageSlidePage(
  //       key: slidePagekey,
  //       child: GestureDetector(
  //         child: ExtendedImage.network(
  //           widget.imageUrl,
  //           enableSlideOutPage: true,
  //           loadStateChanged: _loadStateChanged,
  //           mode: ExtendedImageMode.gesture,
  //           // 设置Hero划出动画
  //           heroBuilderForSlidingPage: (Widget result) {
  //             // return Hero(
  //             //   tag: "${widget.heroTag}",
  //             //   child: result,
  //             //   flightShuttleBuilder: (BuildContext flightContext,
  //             //       Animation<double> animation,
  //             //       HeroFlightDirection flightDirection,
  //             //       BuildContext fromHeroContext,
  //             //       BuildContext toHeroContext) {
  //             //     final Hero hero = (flightDirection == HeroFlightDirection.pop
  //             //         ? fromHeroContext.widget
  //             //         : toHeroContext.widget) as Hero;
  //             //     return hero.child;
  //             //   },
  //             // );
  //             return HeroWidget(
  //               child: result,
  //               tag: "${widget.heroTag}",
  //               slideType: SlideType.onlyImage,
  //               slidePagekey: slidePagekey,
  //             );
  //           },
  //           initGestureConfigHandler: _heroBuilderForSlidingPage,
  //           onDoubleTap: _onDoubleTap,
  //         ),
  //         onTap: () {
  //           slidePagekey.currentState?.popPage();
  //           Navigator.pop(context);
  //         },
  //       ),
  //       slideAxis: SlideAxis.both,
  //       slideType: SlideType.onlyImage,
  //     ),
  //   );
  // }

  /// 图片加载, 可用于控制加载中,加载成功,加载失败时自定义布局
  Widget? _loadStateChanged(ExtendedImageState state) {
    Widget? childWidget;
    switch (state.extendedImageLoadState) {
      case LoadState.failed:
        if (widget.reLoadImage) {
          childWidget = GestureDetector(
            child: Container(
              color: Colors.black12,
              child: Icon(
                Icons.refresh,
                size: 36,
                color: Colors.black12,
              ),
            ),
            onTap: () {
              state.reLoadImage();
            },
          );
        } else {
          childWidget = Image.asset(
            'assets/images/public/default.png',
            // fit: BoxFit.cover,
          );
        }
        break;
      default:
        // 加载成功时与加载中使用默认布局
        break;
    }
    return childWidget;
  }

  GestureConfig _heroBuilderForSlidingPage(ExtendedImageState state) {
    // 设置图片默认显示的比例
    double initialScale = 1.0;
    return GestureConfig(
      inPageView: true,
      initialScale: initialScale,
      minScale: initialScale,
      animationMinScale: 0.9,
      maxScale: max(initialScale, 5.0),
      animationMaxScale: max(initialScale, 5.0),
      initialAlignment: InitialAlignment.center,
      // 即使页面视图页面更改，也可以缓存手势状态。
      // 记住在正确的时间调用clearGestureDetailsCache()方法。(例如，该页面被处理)
      cacheGesture: false,
    );
  }

  /// 双击放大图片, 使用了动画放大方式
  ///
  /// 注意每次执行动画后需要重置双击动画相关参数
  void _onDoubleTap(ExtendedImageGestureState state) {
    // 你可以使用定义pointerDownPosition，
    // 默认值是双击指针向下的位置。
    // 用于控制双击后图片的位置
    final Offset? pointerDownPosition = state.pointerDownPosition;
    final double? begin = state.gestureDetails?.totalScale;
    double end;

    // 移除旧的双击动画监听
    _doubleClickAnimation?.removeListener(_doubleClickAnimationListener!);
    // 停止双击事件
    _doubleClickAnimationController?.stop();
    // 重置双击事件
    _doubleClickAnimationController?.reset();

    // 判断双击状态控制当前显示图片的大小
    if (begin == doubleTapScales[0]) {
      end = doubleTapScales[1];
    } else if (begin == doubleTapScales[1]) {
      end = doubleTapScales[2];
    } else {
      end = doubleTapScales[0];
    }
    // 重新设置双击动画监听
    _doubleClickAnimationListener = () {
      state.handleDoubleTap(
        scale: _doubleClickAnimation?.value,
        doubleTapPosition: pointerDownPosition,
      );
    };
    // 重置双击动画的值
    _doubleClickAnimation = _doubleClickAnimationController!
        .drive(Tween<double>(begin: begin, end: end));
    // 添加新的双击监听
    _doubleClickAnimation?.addListener(_doubleClickAnimationListener!);
    // 执行双击监听
    _doubleClickAnimationController?.forward();
  }

  @override
  void dispose() {
    _doubleClickAnimationController?.dispose();
    clearGestureDetailsCache();
    super.dispose();
  }
}
